using YMJake.Flowable.ExternalWorker.Client.AspNetCore.DependencyInjection;
using YMJake.Flowable.ExternalWorker.Client.Sample.Handlers;

var builder = WebApplication.CreateBuilder(args);

// 添加Flowable External Worker服务
builder.Services.AddFlowableExternalWorker(options =>
{
    options.FlowableHost = "http://localhost:8091/flowable-rest";
    options.BasicAuthUsername = "rest-admin";
    options.BasicAuthPassword = "test";
});

// 配置工作者管道
builder.Services.AddFlowableWorker("processOrder", numberOfWorkers: 2)
    .AddHandler<OrderProcessorHandler>()
    .WithPollingInterval(TimeSpan.FromSeconds(10))
    .ConfigurePipeline(pipeline =>
    {
        // Add logging middleware
        pipeline.Use(next => async context =>
        {
            var logger = context.ServiceProvider.GetRequiredService<ILogger<Program>>();
            logger.LogInformation("Started processing task {JobId} by worker {WorkerId}", 
                context.Job.Id, context.WorkerId);
            
            var stopwatch = System.Diagnostics.Stopwatch.StartNew();
            
            try
            {
                await next(context);
                
                logger.LogInformation("Finished processing task {JobId} in {ElapsedMs}ms", 
                    context.Job.Id, stopwatch.ElapsedMilliseconds);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Failed processing task {JobId} after {ElapsedMs}ms", 
                    context.Job.Id, stopwatch.ElapsedMilliseconds);
                throw;
            }
        });

        // Add retry middleware
        pipeline.Use(next => async context =>
        {
            var maxRetries = 3;
            var retryCount = 0;
            
            while (retryCount <= maxRetries)
            {
                try
                {
                    await next(context);
                    break; // Success, exit retry loop
                }
                catch (Exception ex) when (retryCount < maxRetries)
                {
                    retryCount++;
                    var logger = context.ServiceProvider.GetRequiredService<ILogger<Program>>();
                    logger.LogWarning("Retry {RetryCount}/{MaxRetries} for task {JobId}: {Error}", 
                        retryCount, maxRetries, context.Job.Id, ex.Message);
                    
                    await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, retryCount)), context.CancellationToken);
                }
            }
        });
    });

builder.Services.AddFlowableWorker("sendNotification", numberOfWorkers: 1)
    .AddHandler<NotificationHandler>()
    .ConfigurePipeline(pipeline =>
    {
        // Simple logging middleware
        pipeline.Use(next => async context =>
        {
            var logger = context.ServiceProvider.GetRequiredService<ILogger<Program>>();
            logger.LogInformation("Processing notification {JobId}", context.Job.Id);
            await next(context);
            logger.LogInformation("Notification {JobId} processed", context.Job.Id);
        });
    });

builder.Services.AddFlowableWorker("asyncProcess")
    .AddHandler<AsyncProcessHandler>();

builder.Services.AddFlowableWorker("simpleTask")
    .AddHandler<SimpleTaskHandler>();

var app = builder.Build();

app.Run();